﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using log4net.Core;

namespace Aribaccio.Logger
{
    public class LoggerLeader
    {
        /// <summary>
        /// 是否已初始化
        /// </summary>
        protected bool IsInitialized { get; set; }
        /// <summary>
        /// 日志写入操作辅助
        /// </summary>
        protected LoggerWriter? LogWriter { get; set; }
        /// <summary>
        /// 检测任务线程
        /// </summary>
        protected PeriodicTaskManual MonitorTask { get; set; }
        /// <summary>
        /// 日志信息队列
        /// </summary>
        protected ConcurrentQueue<LoggerMsg> LogDataQueue { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public LoggerLeader()
        {
            this.IsInitialized = false;
            this.LogDataQueue = new ConcurrentQueue<LoggerMsg>();
            this.MonitorTask = new PeriodicTaskManual($"日志服务", 100, MonitorTaskAction, false, false);
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Initialize()
        {
            if (this.IsInitialized) return;
            this.IsInitialized = true;
            this.LogWriter = new LoggerWriter();
            if (this.LogWriter != null)
            {
                var result = this.MonitorTask.Start(true);
                this.WriteInfo(result.ResultMsg ?? (result.ResultState ? "日志服务 => 任务已启动" : "日志服务 => 任务未启动"));
            }
            //注册管理日志中心
            LoggerMgrcore.Instance.Register(this);
        }

        /// <summary>
        /// 终止退出
        /// </summary>
        public void Terminate()
        {
            this.MonitorTask?.Stop();
            while (LogDataQueue.TryDequeue(out _)) { }
        }

        /// <summary>
        /// 刷新
        /// </summary>
        /// <returns></returns>
        public bool Flush()
        {
            return this.LogWriter?.Flush() ?? false;
        }

        /// <summary>
        /// 写入常规日志消息
        /// </summary>
        /// <param name="argMessage">消息内容</param>
        public void WriteInfo(string argMessage)
        {
            this.Write(argMessage, Level.Info);
        }

        /// <summary>
        /// 写入调试日志消息
        /// </summary>
        /// <param name="argMessage">消息内容</param>
        public void WriteDebug(string argMessage)
        {
            this.Write(argMessage, Level.Debug);
        }

        /// <summary>
        /// 写入告警日志消息
        /// </summary>
        /// <param name="argMessage">消息内容</param>
        public void WriteWarning(string argMessage)
        {
            this.Write(argMessage, Level.Warn);
        }

        /// <summary>
        /// 写入错误/异常日志消息
        /// </summary>
        /// <param name="argMessage">消息内容</param>
        /// <param name="argException">消息异常对象</param>
        public void WriteError(string argMessage, Exception? argException = null)
        {
            this.Write(argMessage, Level.Error, argException);
        }

        /// <summary>
        /// 写入日志消息
        /// </summary>
        /// <param name="argMessage">消息内容</param>
        /// <param name="argLevel">消息等级</param>
        /// <param name="argException">消息异常对象</param>
        public void Write(string argMessage, Level argLevel, Exception? argException = null)
        {
            this.LogDataQueue.Enqueue(new LoggerMsg(argMessage, argLevel, argException));
        }

        /// <summary>
        /// 执行线程任务
        /// </summary>
        protected void MonitorTaskAction()
        {
            if (this.LogWriter == null) return;
            //循环读取队列数据
            while (this.LogDataQueue.TryDequeue(out LoggerMsg? curLogMsg))
            {
                this.LogWriter.WriteLogMsg(curLogMsg);
            }
        }
    }
}
